#ifndef __H_KC031SRV_H__
#define __H_KC031SRV_H__
#include "mt_timer.h"

#include "ini.h"
#include "utils.h"
#include "xLogMessage.h"
#include "mod_gpio.h"

#define PSUSERVICE_TAG "PSUSERVICE"

#define PSU_DEBUG

#define SYS_DEBUG

//#define USE_UEVENT

#define USE_MQTT
#define USE_LUA


/*定义本文件中使用的打印日志、告警和错误的宏
 */
#define PSUS_EENDLINE	"\n"
#define psus_log(level, fmt, args...) 		LogMessage(level, __FILE__, __LINE__, PSUSERVICE_TAG, fmt, ##args)
#define psus_error(fmt, args...) 			LogErrorMessage(__FILE__, __LINE__, PSUSERVICE_TAG, fmt, ##args)
#define psus_warning(fmt, args...) 			LogWarningMessage(__FILE__, __LINE__, PSUSERVICE_TAG, fmt, ##args)
#define psus_hint(fmt, args...) 			LogMessage(4, __FILE__, __LINE__, PSUSERVICE_TAG, fmt, ##args)

#define IP2STR(ip) (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF

#define MAX_PATH 260
#define MAX(a, b) ((a > b) ? (a) : (b))
#define MIN(a, b) ((a < b) ? (a) : (b))

#define INVAILDSOCKET -1
#define getconf_string(param)		(param==NULL?"":param)

#ifdef ANDROIDEX
#define DEFAULT_ROOT_PATH "/data/log/"
#define DEFAULT_LOG_FILE DEFAULT_ROOT_PATH "kc031srv.log"
#else
#define DEFAULT_ROOT_PATH "/tmp/log/"
#define DEFAULT_LOG_FILE DEFAULT_ROOT_PATH "kc031srv.log"
#endif

typedef enum{
	AEX_ETYPE_NONE,				//不使用加密
	AEX_ETYPE_SOFT,				//使用软加密
	AEX_ETYPE_DTTF,				//使用大唐的TF加密卡
}LIST_ETYPE;
/**
 * 设备使用的服务器类型
 */
typedef enum{
	AEX_SERVER_MQTT,				//使用MQTT服务器
	AEX_SERVER_TCP,					//使用TCP服务器
	AEX_SERVER_UDP,					//使用uDP服务器
	AEX_SERVER_NONE,				//不使用服务器
}LIST_SERVER_TYPE;
/**
 * 串口数据的处理方式，多个串口时会为每隔串口配置不同的操作方式
 */
typedef enum{
	AEX_UART_PACKNET,				//UART数据首先作为命令数据解析，如果不是命令数据则送给脚本处理
	AEX_UART_PACKET_SERVER,			//UART数据打包发送给UDP服务器
	AEX_UART_PASSTO_LUA,			//直接将串口数据给脚本处理
	AEX_UART_PACKET_MODBUS,			//UART接MODBUS设备
}LIST_UART_PASSTO;

typedef enum{
	AEX_UART_RS232 = 0x0,
	AEX_UART_RS485 = 0x01,
	AEX_UART_PROFIBUS = 0x02,
}LIST_UART_TYPE;

/**
 * 最后一条命令的来源
 */
typedef enum{
	AEX_LCF_NONE,					//未知，还没收到过命令
	AEX_LCF_UART,					//最后一条命令来自UART
	AEX_LCF_TCP,					//最后一条命令来自TCP服务器
	AEX_LCF_UDP,					//最后一条命令来自UDP服务器
	AEX_LCF_MQTT,					//最后一条命令是MQTT发送的
	AEX_LCF_ME,						//最后一条命令来自本机
}LIST_LAST_CMD_FROM;

typedef struct {
	int uart_used;			//是否启用UART串口
	char *port;			//串口的地址及打开参数，如/dev/ttyS0,115200,1,N,8
	int uart_fd;		//串口的文件句柄
	int type;			//串口类型，RS232/RS485/ProfiBus
	LIST_UART_PASSTO passto;			//RS232数据处理方式
}UARTDATA,*PUARTDATA;

/* define the config struct type */
typedef struct
{
	int flag;					 //日志输出类别
	unsigned short minLevel;	 //日志级别的最小值
	unsigned short maxLevel;	 //日志级别的最大值
	int selectTimeout;			 // Select等待的超时时间
	int localport;				 //TCP/UDP服务使用的本地端口
	int nettype;				 //与服务器通讯的类型：MQTT/TCP/UDP
	struct sockaddr_in tcp_addr; //提供TCP服务器的地址和端口
	struct sockaddr_in udp_addr; //提供UDP服务器的地址和端口
	int hasgpio;				//是否启用输入GPIO的定时检测，如果中断不起作用时使用此功能检测输入引脚的变化
	int tcp_fd;					 //存储TCP的Socket文件描述符
	int udp_fd;					 //存储UDP通讯的Socket文件描述符
	UARTDATA bsuart;				//RS485使用的UART
	UARTDATA uarts[MAX_UART_NUM];	//额外使用的串口

	LIST_LAST_CMD_FROM last_cmd_from;	//存储最后一条数据的来源，这决定了后面给谁回复数据
	int uevent_fd;
	LIST_ETYPE etype;			//加密类型
	unsigned char ekey[16];		//加密密钥
}HCS_DATA;

typedef struct
{
	#define CFG(s, n, default) char *s##_##n;
	#include "psuservice.def"
	HCS_DATA hcsdata;
} psus_config;

#define getconf_string(param)		(param==NULL?"":param)
psus_config *get_psus_data(void);
int get_tcp_connected();
// int SendUdpSocket(psus_config *psudata,char *buf,int len);
int StartUdpSocket(psus_config *psudata);
int StartTcpSocket(psus_config *psudata);
void CloseTcpSocket(psus_config *psudata);
int SendRspSocket(psus_config *psudata, char *buf, int len);

int fok_for_timer(unsigned int mseconds,unsigned int seconds);
void exit_for_fok();

#define KC031SRV_HEART_DELAY		10
#define KC031SRV_HEART_INTERVAL		120

#define KC031SRV_CHKINPUT_DELAY		100000000
#define KC031SRV_CHKINPUT_INTERVAL	100000000

#define  TIMERMSG_TRYTCPCONNECT		0x00000001		//
#define  TIMERMSG_HEART_DATA		0x00000002		// UDP心跳数据包周期

#define HCSRV_HEART_DELAY			5
#define HCSRV_HEART_INTERVAL		5

#define MS_DELAY_FORK	500	//延时500ms，在需要fork进程时的延时启动

void start_chkinput();
void start_heart();
unsigned long get_heating_inv();
int SendtoServer(char *buf, int len);
int SendtoRS485Bus(psus_config *psudata,unsigned char dstaddr, unsigned char cmd,char *buf, int len);
int OpenUart(UARTDATA *puart);
void CloseUart(UARTDATA *puart);

// void dump_buffer(char *pstr, int size);

int get_heating_used();
int modbusmain();
int modbus_stop_vrv();
int modbus_pwr(int addr,int nreg);

#endif //__H_KC031SRV_H__
